<?php
/**
 * 公共函数类
 * 
 * @author fuyou
 * @since May 14, 2015 9:44:29 AM
 * @version 2.0
 * @copyright 
 *
 */
class LibComFunc {
    /**
     * API输出
     *
     * @param type $Template
     *            输出结果
     */
    public static function exportResult($Template) {
        if (LibAppInit::$IS_DEBUG) {
            echo "<pre>";
            var_dump ( $Template );
            echo "</pre>";
        }
        header ( 'Content-type: application/json' );
        json_encode ( json_encode ( $Template ) );
    }
    
    /**
     * 逻辑错误退出
     *
     * @param int $error_code            
     * @param string $error_msg
     *            错误信息，如果是系统级错误，可置空
     * @param array $added_info            
     *
     */
    public static function errorExit($errorCode, $errorMsg = '', $added_info = array()) {
        if ($errorMsg == '') {
            $errorMsg = LibAppInit::$sysError [$errorCode];
        }
        $Template = array (
                'errorCode' => $errorCode,
                'errorMsg' => $errorMsg 
        );
        
        if (! empty ( $added_info )) {
            $Template = array_merge ( $Template, $added_info );
        }
        die ( json_encode ( $Template ) );
    }
    
    /**
     * iphone客户端custid加密
     *
     * @param unknown_type $type
     *            generate or verify
     * @param unknown_type $cust_id            
     * @param unknown_type $code            
     */
    public static function iphoneEncodeCustid($type, $custid, $code = '') {
        $prefix = 'z6o7w3i';
        if (! $custid) {
            return false;
        }
        $custid = $prefix . $custid;
        $gen_code = substr ( md5 ( $custid ), 2, 12 );
        if ($type == 'generate') { // 生成密码
            return $gen_code;
        }
        if ($type == 'verify') { // 检验密码
            if ($code == $gen_code) {
                return true;
            } else {
                return false;
            }
        }
    }
    
    /**
     * 生成验证码图片请求KEY
     *
     * @param type $app_id            
     * @return string
     */
    public static function genVcode($app_id, $udid = null) {
        $vcode = md5 ( microtime ( true ) . rand ( 0, 10000 ) . $udid );
        $vcode = $app_id . '_' . $vcode;
        return $vcode;
    }
    
    /**
     * 二维数组排序
     *
     * @param type $arr
     *            排序数组
     * @param type $keys
     *            按照那个字段排序
     * @param type $type
     *            排序方式,asc,desc
     * @return type
     */
    public static function arraySort($arr, $keys, $type = 'asc') {
        $keysvalue = $new_array = array ();
        foreach ( $arr as $k => $v ) {
            $keysvalue [$k] = $v [$keys];
        }
        if ($type == 'asc') {
            asort ( $keysvalue );
        } else {
            arsort ( $keysvalue );
        }
        reset ( $keysvalue );
        foreach ( $keysvalue as $k => $v ) {
            $new_array [$k] = $arr [$k];
        }
        return $new_array;
    }
    /**
     * 输入数据处理
     *
     * @return array
     * @since May 14, 2015 9:29:30 AM
     * @access
     *
     */
    public static function processGetPost() {
        $clean_gp = array ();
        $_GET = deep_add_slashes ( $_GET );
        $_POST = deep_add_slashes ( $_POST );
        foreach ( array_merge ( $_POST, $_GET ) as $k => $v ) {
            $clean_gp [$k] = is_array ( $v ) ? $v : trim ( $v );
        }
        return $clean_gp;
    }
    
    /**
     * 为输入参数添加slash
     *
     * @param unknown $var            
     * @return string
     * @since May 14, 2015 9:48:13 AM
     * @access
     *
     */
    public static function deepAddSlashes($var) {
        if (is_array ( $var )) {
            foreach ( $var as $key => $val ) {
                $var [$key] = deep_add_slashes ( $val );
            }
        } else {
            $var = addslashes ( $var );
        }
        return $var;
    }
    /**
     * $_SERVER['HTTP_REFERER']
     *
     * @return unknown
     */
    public static function getPageRefer() {
        return $_SERVER ['HTTP_REFERER'];
    }
    
    /**
     * 获取本页的URL地址
     *
     * @param bool $absolute
     *            是否取全地址
     * @access public
     * @return string
     */
    public static function getPageUrl($absolute = true) {
        $host = $_SERVER ['HTTP_HOST'];
        $host = str_replace ( ':8000', '', $host );
        $port = ($_SERVER ['SERVER_PORT'] == 8000 || $_SERVER ['SERVER_PORT'] == 80 || $_SERVER ['SERVER_PORT'] == 443 || $_SERVER ['SERVER_PORT'] == 888) ? '' : ":{$_SERVER['SERVER_PORT']}";
        $uri = $_SERVER ['REQUEST_URI'];
        $protocal = $_SERVER ['SERVER_PORT'] == 443 ? 'https://' : 'http://';
        return $absolute ? $protocal . $host . $port . $uri : $uri;
    }
    
    /**
     * 转换编码，m.dd通常是转换为utf-8
     *
     * @param string $string
     *            要转换的字符串
     * @param string $toencode
     *            要转换为的编码,默认为UTF-8
     * @return string
     */
    public static function convertEncoding($string, $to_encode = 'UTF-8') {
        // 当前编码
        $now_encode = detect_encode ( $string );
        // 只有编码不同时才转换
        if (strtolower ( $to_encode ) != strtolower ( $now_encode )) {
            $string = mb_convert_encoding ( $string, $to_encode, $now_encode );
        }
        return $string;
    }
    public static function auto_convert(&$string) {
        $string = convert_encoding ( $string );
    }
    
    /**
     * 检测字符串当前编码
     *
     * @param string $string
     *            需要检测的字符串
     * @access public
     * @return string 字符编码:UTF-8,...
     */
    public static function detectEncode($string) {
        $encodes = array (
                'ASCII',
                'UTF-8',
                'GBK',
                'GB2312',
                'CP936' 
        );
        $now_encode = mb_detect_encoding ( $string, $encodes );
        if (false === $now_encode) { // user reco 为什么返回的东西就不能分析出编码呢...
            return 'CP936';
        }
        return $now_encode;
    }
    
    /**
     * 转换gbk=>utf-8
     *
     * @param unknown_type $string            
     */
    public static function autoConvertGbkToUtf8(&$string) {
        $string = mb_convert_encoding ( $string, 'UTF-8', 'GBK' );
    }
    /**
     * 格式化00.00 原实现方法有bug...so改成sprintf的
     */
    public static function convertFloatWith2decimals($float_char) {
        return sprintf ( "%.02f", floatval ( $float_char ) );
    }
    
    /**
     * 计算时间段 原名date_diff 与php5.3冲突...so 改名date_diff_dd
     *
     * @param <type> $start            
     * @param <type> $end            
     * @return <type>
     */
    public static function dateDiffdd($start, $end = "") {
        $sdate = strtotime ( $start );
        if ($end == '') {
            $end = date ( "Y-m-d H:i:s", time () );
        }
        $edate = strtotime ( $end );
        if ($start > $end) {
            return false;
        }
        $time = $edate - $sdate;
        if ($time >= 0 && $time <= 59) {
        } elseif ($time >= 60 && $time <= 3599) {
            $pmin = ($edate - $sdate) / 60;
            $premin = explode ( '.', $pmin );
            $presec = $pmin - $premin [0];
            $sec = $presec * 60;
            $timeshift = $premin [0] . '分';
        } elseif ($time >= 3600 && $time <= 86399) {
            $phour = ($edate - $sdate) / 3600;
            $prehour = explode ( '.', $phour );
            $premin = $phour - $prehour [0];
            $min = explode ( '.', $premin * 60 );
            $presec = '0.' . $min [1];
            $sec = $presec * 60;
            // $timeshift = $prehour[0].'小时'.$min[0].'分'.round($sec,0).'秒';
            $timeshift = $prehour [0] . '小时' . $min [0] . '分';
        } elseif ($time >= 86400) {
            // Days + Hours + Minutes
            $pday = ($edate - $sdate) / 86400;
            $preday = explode ( '.', $pday );
            $phour = $pday - $preday [0];
            $prehour = explode ( '.', $phour * 24 );
            $premin = ($phour * 24) - $prehour [0];
            $min = explode ( '.', $premin * 60 );
            $presec = '0.' . $min [1];
            $sec = $presec * 60;
            // $timeshift = $preday[0].'天'.$prehour[0].'小时'.$min[0].'分'.round($sec,0).'秒';
            $timeshift = $preday [0] . '天' . $prehour [0] . '小时' . $min [0] . '分';
        }
        return $timeshift;
    }
    
    /**
     * Enter description here...
     *
     * @param unknown_type $datetime            
     * @return unknown
     */
    public static function convertDatetimeStrToArray($datetime) {
        $temp = explode ( " ", $datetime );
        $date_array = explode ( '-', $temp [0] );
        $time_array = explode ( ':', $temp [1] );
        $date_time_array ['Y'] = $date_array [0];
        $date_time_array ['m'] = $date_array [1];
        $date_time_array ['d'] = $date_array [2];
        $date_time_array ['H'] = $time_array [0];
        $date_time_array ['i'] = $time_array [1];
        $date_time_array ['s'] = $time_array [2];
        return $date_time_array;
    }
    
    /**
     * 转换XML文件编码，主要针对GBK[2312]或者GBK编码的进行处理, 同时去掉可能影响XML解析错误的字符
     *
     * @param string $xml_string
     *            要转换的字符串
     * @param string $encode
     *            要转换为的编码,默认为UTF-8
     * @access public
     * @return string
     */
    public static function convertXmlEncode($xml_string, $encode = 'UTF-8') {
        $now_encode = detect_encode ( $xml_string );
        $xml_string_arr = explode ( '?>', $xml_string );
        if (preg_match ( "/(^<\?xml.*?encoding=\")GB2312|GBK(.*)/i", trim ( $xml_string_arr [0] ) )) {
            $xml_string_arr [0] = preg_replace ( "/(^<\?xml.*?encoding=\")GB2312|GBK(.*)/i", '${1}' . $encode . '${2}', trim ( $xml_string_arr [0] ) ); // 如果头部声明是GB2312则替换为$encode
        }
        $xml_string = implode ( '?>', $xml_string_arr );
        $xml_string = mb_convert_encoding ( $xml_string, 'UTF-8', $now_encode );
        return $xml_string;
    }
    
    /**
     * 过滤URL string中的元素
     *
     * @param string $url
     *            请求的URL地址
     * @access public
     * @return string 响应字符串
     */
    public static function setDefaultValue($input_array, $default_values) {
        foreach ( $input_array as $key => $value ) {
            if (! is_array ( $value )) {
                if ("CP936" == detect_encode ( $value ))
                    auto_convert_gbk_to_utf8 ( $value );
                $input_array [$key] = filterxss ( htmlentities ( $value, ENT_QUOTES, "UTF-8" ) );
            } else {
                foreach ( $value as $sub_key => $sub_value ) {
                    if ("CP936" == detect_encode ( $sub_value ))
                        auto_convert_gbk_to_utf8 ( $sub_value );
                    $value [$sub_key] = filterxss ( htmlentities ( $sub_value, ENT_QUOTES, "UTF-8" ) );
                }
                $input_array [$key] = $value;
            }
        }
        // 设置默认值
        foreach ( $default_values as $key => $value ) {
            if (! isset ( $input_array [$key] ) || (empty ( $input_array [$key] ) && $input_array [$key] != 0)) {
                $input_array [$key] = $value;
            }
        }
        return $input_array;
    }
    /**
     * 过滤Xss
     *
     * @param unknown $str            
     * @return string
     * @since May 14, 2015 9:49:25 AM
     * @access
     *
     */
    public static function filterXSS($str) {
        $str = trim ( $str );
        $str = strip_tags ( $str );
        return $str;
    }
    
    /**
     * 判断是否为搜索引擎
     *
     * @access public
     * @return bool
     */
    public static function isRobot() {
        $ua = $_SERVER ['HTTP_USER_AGENT'];
        $kw_spider = 'Bot|Crawl|Spider|slurp|sohu-search|lycos|robozilla|mobier|heritrix';
        if (preg_match ( "/($kw_spider)/i", $ua )) {
            header ( 'Location:http://www.dangdang.com' );
            exit ();
            return true;
        } else {
            return false;
        }
    }
    public static function getRealIp($need_long = false) {
        if (isset ( $_SERVER )) {
            if (isset ( $_SERVER ['HTTP_X_FORWARDED_FOR'] )) {
                $ip = $_SERVER ['HTTP_X_FORWARDED_FOR'];
            } elseif (isset ( $_SERVER ['HTTP_CLIENT_IP'] )) {
                $ip = $_SERVER ['HTTP_CLIENT_IP'];
            } else {
                $ip = $_SERVER ['REMOTE_ADDR'];
            }
        } else {
            if (getenv ( 'HTTP_X_FORWARDED_FOR' )) {
                $ip = getenv ( 'HTTP_X_FORWARDED_FOR' );
            } elseif (getenv ( 'HTTP_CLIENT_IP' )) {
                $ip = getenv ( 'HTTP_CLIENT_IP' );
            } else {
                $ip = getenv ( 'REMOTE_ADDR' );
            }
        }
        if (true == $need_long) {
            $ip = ip2long ( $ip ); // !!32bit 64bit calculated result not same... so suggest not use it. and use the MySQL function INET_ATON,INET_NTOA with UNSIGNED INT(11) field
        }
        return $ip;
    }
    
    /**
     * 生成一个全局唯一的ID 主要来生成permanent_id & trace_id
     * 暂时保留原生成方法(ycg@0608)
     *
     * @return string
     */
    public static function genGuid() {
        $guid = '';
        $mt = explode ( ' ', microtime () );
        $ms = '00' . $mt [0];
        $start = strlen ( $ms );
        $ms = substr ( $ms, $start - 3, 3 );
        $guid = date ( 'YmdHis' ) . $ms . rand ( 100000, 999999 ) . rand ( 100000, 999999 ) . rand ( 100000, 999999 );
        return $guid;
    }
    
    /**
     * stdCls to array
     * 一般用于json_decode完,升成的object
     *
     * @param object $obj            
     * @return array
     */
    public static function object2Array($obj) {
        if (is_array ( $obj ) || is_object ( $obj )) {
            $new_arr = array ();
            foreach ( $obj as $key => $row ) {
                $new_arr [$key] = object_2_array ( $row );
            }
            return $new_arr;
        } else { // 叶子节点
            return $obj;
        }
    }
    
    /**
     * 数组分页, 页码从0开始
     *
     * @param type $source_ary
     *            源数组
     * @param type $page_num
     *            页码
     * @param type $page_size
     *            页宽
     * @return type
     */
    public static function multiPagerForAry($source_ary, $page_num, $page_size) {
        $total = count ( $source_ary );
        $page_max = (( int ) (ceil ( $total / $page_size ))) - 1;
        $curr_page_elements = array_slice ( $source_ary, $page_num * $page_size, $page_size );
        return array (
                'page_info' => array (
                        'page_num' => $page_num,
                        'page_max' => $page_max,
                        'total_count' => $total 
                ),
                'page_content' => $curr_page_elements 
        );
    }
    
    /**
     * 分页
     *
     * @param int $count
     *            总记录数
     * @param int $pagesize
     *            每页条数
     * @param int $page
     *            当前页码
     * @access public
     * @return array array(total => 总记录数, page_count => 总页数, next => 下一页, prev => 上一页, page => 当前页, followup => 以数组形式返回URL string, followup_string => 以字符串型是返回URL string)
     */
    public static function multiPage($count, $pagesize, $page) {
        $page_count = ceil ( $count / $pagesize );
        if ($page > $page_count)
            $page = $page_count;
        if ($page < 1)
            $page = 1;
        $multi = array ();
        $multi ['total'] = $count;
        $multi ['page_count'] = $page_count;
        $multi ['start'] = ($page - 1) * $pagesize;
        $end = $multi ['start'] + $pagesize;
        $multi ['end'] = $end > $count ? $count : $end;
        if ($page < $page_count) {
            $multi ['next'] = $page + 1;
        }
        if ($page > 1) {
            $multi ['prev'] = $page - 1;
        }
        $multi ['page'] = $page;
        $multi ['pagesize'] = $pagesize;
        return $multi;
    }
    public static function multipageFollowUops($followups) {
        $multi = array ();
        $multi ['followups'] = $followups;
        $multi ['followup_string'] = '';
        if (! empty ( $followups )) {
            foreach ( $followups as $followup ) {
                foreach ( $followup as $key => $value ) {
                    $multi ['followup_string'] .= '&amp;' . $key . '=' . $value;
                }
            }
        }
        return $multi;
    }
    
    /**
     * 精简字段
     *
     * @param
     *            &$arr
     * @param
     *            $allow_keys
     * @return
     *
     */
    public static function reduceKey(&$arr, $allow_keys = array(), $reverse = false) {
        if (is_array ( $arr ) && is_array ( $allow_keys )) {
            if (! $reverse) { // 正向过滤
                foreach ( $arr as $key => $row ) {
                    if (! in_array ( $key, $allow_keys )) {
                        unset ( $arr [$key] );
                    }
                }
            } else { // 反向过滤
                foreach ( $arr as $key => $row ) {
                    if (in_array ( $key, $allow_keys )) {
                        unset ( $arr [$key] );
                    }
                }
            }
        }
        return;
    }
    
    /**
     * 针对二位数组进行reduce
     *
     * @param
     *            &$arr
     * @param
     *            $allow_keys
     */
    public static function reduceKeyDeep(&$arr, $allow_keys = array()) {
        if (is_array ( $arr )) {
            foreach ( $arr as $key => $row ) {
                reduce_key ( $arr [$key], $allow_keys );
            }
        }
    }
    
    /**
     * 判断字符串中是否只含有数字或者逗号","
     *
     * @param type $str
     *            需要判定的字符串
     * @return boolean 只含有数字或者逗号，返回TRUE，其他返回FALSE
     */
    public static function sqlstrFilter($str) {
        $result = FALSE;
        if (preg_match ( "/^[\d,\'\"]+$/", $str ) === 1) {
            $result = TRUE;
        }
        return $result;
    }
    
    /**
     * 过滤html标签
     *
     * @param String $content
     *            html内容
     * @param String $tag
     *            需要过滤的标签，默认a标签
     * @param boolean $ident
     *            是否保留标签间的文案，默认过滤
     * @since 2015-1-28 上午11:54:27
     * @access
     *
     * @return $content
     */
    public static function deleteTags($content, $tag = 'a', $ident = false) {
        if ($ident) {
            $content = preg_replace ( "#<{$tag}[^>]*>(.*?)</{$tag}>#is", "$1", $content );
        } else {
            $content = preg_replace ( "/(<$tag.*?>[\s\S]*?<\/$tag>)/", '', $content );
        }
        return $content;
    }
    /**
     * 加载模板 出
     *
     * @param unknown $name            
     * @param array $assigns
     *            传递内容
     * @since 2015年4月22日 下午4:35:39
     * @access
     *
     * @return return_type
     */
    public static function template($name, $assigns) {
        require_once TEMPLATE_PATH . '/' . $name . '.php';
        exit ();
    }
    /**
     * 生成毫秒
     *
     * @return number
     * @since May 25, 2015 3:38:31 PM
     * @access
     *
     */
    public static function makeMillSeconds() {
        $arr_time = split ( ' ', microtime () );
        $micro_second = floor ( $arr_time [0] * 1000 );
        $var_tmp = time () * 1000;
        $my_value = $var_tmp + $micro_second;
        return $my_value;
    }
    /**
     * 生成taceid
     *
     * @since May 26, 2015 2:38:31 PM
     * @access
     *
     */
    public static function genTraceId() {
        $guid = '';
        $mt = explode ( ' ', microtime () );
        $ms = '00' . $mt [0];
        $start = strlen ( $ms );
        $ms = substr ( $ms, $start - 3, 3 );
        $guid = date ( 'YmdHis' ) . $ms . rand ( 100000, 999999 ) . rand ( 100000, 999999 ) . rand ( 100000, 999999 );
        return $guid;
    }
    /**
     * 生成校验码
     *
     * @since Jun 2, 2015 2:08:33 PM
     * @access
     *
     */
    public static function genTimeCode($timestamp, $udid, $action, $user_client, $encodeStr) {
        $time_code = '';
        if (empty ( $timestamp ) || empty ( $udid ) || empty ( $action ) || empty ( $user_client )) {
            return $time_code;
        }
        $clientStr = $encodeStr [$user_client];
        if (empty ( $clientStr )) {
            return $time_code;
        }
        $time_code = strtolower ( md5 ( sprintf ( "%s,%s,%s,%s", $action, $timestamp, $clientStr, $udid ) ) );
        return $time_code;
    }
    /**
     * 去除参数中的空格
     * 
     * @param array $params            
     * @return string
     * @since Jun 10, 2015 2:50:16 PM
     * @access
     *
     */
    public static function trimSpace($params) {
        if (! empty ( $params )) {
            if (is_array ( $params )) {
                foreach ( $params as $key => $pra ) {
                    $params [$key] = trim ( $pra );
                }
            } else {
                $params = trim ( $params );
            }
        }
        return $params;
    }
}